﻿using System;
using System.Diagnostics.Contracts;

namespace OpenLS.Spreadsheet
{
    internal class IconSetInformation
    {
        private readonly IconSet _iconSet;
        private readonly bool _reversed;
        private readonly double max;
        private readonly double min;
        private readonly double value;

        public IconSetInformation(double d, double min, double max, bool reversed, IconSet iconSet)
        {
            value = d;
            this.min = min;
            this.max = max;
            _reversed = reversed;
            _iconSet = iconSet;
        }

        public IconType Icon
        {
            get
            {
                int iconCount = _iconSet.IconCount - 1;

                int id;
                if (max > min)
                    id = (int) (iconCount*(value - min)/(max - min));
                else
                {
                    id = iconCount;
                }
                if (_reversed)
                    id = iconCount - id;
                return GetIconType(id);
            }
        }

        private IconType GetIconType(int id)
        {
            Contract.Requires(id >= 0);
            Contract.Requires(id < _iconSet.IconCount);
            switch (_iconSet.Type)
            {
                case IconSetType.FiveArrows:
                    switch (id)
                    {
                        case 4:
                            return IconType.GreenUpArrow;
                        case 3:
                            return IconType.YellowUpRightArrow;
                        case 2:
                            return IconType.YellowRightArrow;
                        case 1:
                            return IconType.YellowDownRightArrow;
                        case 0:
                            return IconType.RedDownArrow;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.FiveArrowsGray:
                    switch (id)
                    {
                        case 4:
                            return IconType.GrayUpArrow;
                        case 3:
                            return IconType.GrayUpRightArrow;
                        case 2:
                            return IconType.GrayRightArrow;
                        case 1:
                            return IconType.GrayDownRightArrow;
                        case 0:
                            return IconType.GrayDownArrow;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.FiveQuarters:
                    switch (id)
                    {
                        case 4:
                            return IconType.BlackCircleWithBorder;
                        case 3:
                            return IconType.BlackCircleWithOneWhiteQuarter;
                        case 2:
                            return IconType.BlackCircleWithTwoWhiteQuarters;
                        case 1:
                            return IconType.BlackCircleWithThreeWhiteQuarters;
                        case 0:
                            return IconType.WhiteCircleWithBlackBorder;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.FiveRating:
                    switch (id)
                    {
                        case 0:
                            return IconType.SignalMeterWithNoFillBar;
                        case 1:
                            return IconType.SignalMeterWithOneFillBar;
                        case 2:
                            return IconType.SignalMeterWithTwoFillBars;
                        case 3:
                            return IconType.SignalMeterWithThreeFillBars;
                        case 4:
                            return IconType.SignalMeterWithFourFillBars;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.FourArrows:
                    switch (id)
                    {
                        case 3:
                            return IconType.GreenUpArrow;
                        case 2:
                            return IconType.YellowUpRightArrow;
                        case 1:
                            return IconType.YellowDownRightArrow;
                        case 0:
                            return IconType.RedDownArrow;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.FourArrowsGray:
                    switch (id)
                    {
                        case 3:
                            return IconType.GrayUpArrow;
                        case 2:
                            return IconType.GrayUpRightArrow;
                        case 1:
                            return IconType.GrayDownRightArrow;
                        case 0:
                            return IconType.GrayDownArrow;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.FourRating:
                    switch (id)
                    {
                        case 0:
                            return IconType.SignalMeterWithOneFillBar;
                        case 1:
                            return IconType.SignalMeterWithTwoFillBars;
                        case 2:
                            return IconType.SignalMeterWithThreeFillBars;
                        case 3:
                            return IconType.SignalMeterWithFourFillBars;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.FourRedToBlack:
                    switch (id)
                    {
                        case 3:
                            return IconType.RedCircle;
                        case 2:
                            return IconType.PinkCircle;
                        case 1:
                            return IconType.GrayCircle;
                        case 0:
                            return IconType.BlackCircle;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.FourTrafficLights:
                    switch (id)
                    {
                        case 3:
                            return IconType.GreenCircle;
                        case 2:
                            return IconType.YellowCircle;
                        case 1:
                            return IconType.RedCircle;
                        case 0:
                            return IconType.BlackCircle;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.ThreeArrows:
                    switch (id)
                    {
                        case 2:
                            return IconType.GreenUpArrow;
                        case 1:
                            return IconType.YellowRightArrow;
                        case 0:
                            return IconType.RedDownArrow;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.ThreeArrowsGray:
                    switch (id)
                    {
                        case 2:
                            return IconType.GrayUpArrow;
                        case 1:
                            return IconType.GrayRightArrow;
                        case 0:
                            return IconType.GrayDownArrow;

                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.ThreeFlags:
                    switch (id)
                    {
                        case 2:
                            return IconType.GreenFlag;
                        case 1:
                            return IconType.YellowFlag;
                        case 0:
                            return IconType.RedFlag;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.ThreeSigns:
                    switch (id)
                    {
                        case 2:
                            return IconType.GreenCheckSymbol;
                        case 1:
                            return IconType.YellowExclamationSymbol;
                        case 0:
                            return IconType.RedCrossSymbol;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.ThreeSymbols:
                    switch (id)
                    {
                        case 2:
                            return IconType.GreenCheckSymbol;
                        case 1:
                            return IconType.YellowExclamationSymbol;
                        case 0:
                            return IconType.RedCrossSymbol;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.ThreeSymbols2:
                    switch (id)
                    {
                        case 2:
                            return IconType.GreenCheckSymbol;
                        case 1:
                            return IconType.YellowExclamationSymbol;
                        case 0:
                            return IconType.RedCrossSymbol;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.ThreeTrafficLights1:
                    switch (id)
                    {
                        case 2:
                            return IconType.GreenTrafficLight;
                        case 1:
                            return IconType.YellowTrafficLight;
                        case 0:
                            return IconType.RedTrafficLight;
                        default:
                            throw new NotSupportedException();
                    }
                case IconSetType.ThreeTrafficLights2:
                    switch (id)
                    {
                        case 2:
                            return IconType.GreenTrafficLight;
                        case 1:
                            return IconType.YellowTrafficLight;
                        case 0:
                            return IconType.RedTrafficLight;
                        default:
                            throw new NotSupportedException();
                    }

                default:
                    throw new NotSupportedException();
            }
        }
    }

    internal enum IconType
    {
        GreenUpArrow,
        YellowRightArrow,
        RedDownArrow,
        GrayUpArrow,
        GrayRightArrow,
        GrayDownArrow,
        GreenFlag,

        YellowFlag,
        RedFlag,
        GreenCircle,
        RedCircleWithBorder,
        YellowCircle,
        BlackCircleWithBorder,
        GreenTrafficLight,
        RedTrafficLight,
        YellowTrafficLight,
        YellowTriangle,
        RedDiamond,
        GreenCheckSymbol,
        YellowExclamationSymbol,
        RedCrossSymbol,
        GreenCheck,
        YellowExclamation,
        RedCross,
        YellowUpRightArrow,
        YellowDownRightArrow,
        GrayUpRightArrow,
        GrayDownRightArrow,
        RedCircle,
        PinkCircle,
        GrayCircle,
        BlackCircle,
        BlackCircleWithOneWhiteQuarter,
        BlackCircleWithTwoWhiteQuarters,
        BlackCircleWithThreeWhiteQuarters,
        WhiteCircleWithBlackBorder,
        SignalMeterWithNoFillBar,
        SignalMeterWithOneFillBar,
        SignalMeterWithTwoFillBars,
        SignalMeterWithThreeFillBars,
        SignalMeterWithFourFillBars,
        GoldStar,
        HalfGoldStar,
        SilverStar,
        GreenUpTriangle,
        YellowDash,
        RedDownTriangle,
        FourFilledBoxes,
        ThreeFilledBoxes,
        TwoFilledBoxes,
        OneFilledBox,
        ZeroFilledBoxes
    }
}